home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 245_01 / lca32.c < prev    next >
Text File  |  1987-10-26  |  10KB  |  351 lines

  1.  
  2. /* (3,2) linear cellular automaton    */
  3. /*                    */
  4. /* Reference:                */
  5. /*                    */
  6. /*    Kenneth E. Perry            */
  7. /*    Abstract Mathematical Art        */
  8. /*    BYTE                */
  9. /*    December, 1986            */
  10. /*    pages 181-192            */
  11.  
  12. /*    Copyright (C) 1987        */
  13. /*    Harold V. McIntosh        */
  14. /*    Gerardo Cisneros S.        */
  15.  
  16. /* G. Cisneros, 4.3.87 */
  17. /* 10 April 1987 - Adapted for second neighbors [HVM] */
  18. /* 25 April 1987 - Collection of sample rules [HVM] */
  19. /* 26 April 1987 - Multiple menus [HVM] */
  20. /* 28 April 1987 - version for XVI Feria de Puebla [HVM] */
  21. /* 16 May 1987 - adapted for (3,2) [HVM] */
  22.  
  23. # include <bdos.h>
  24.  
  25. # define COLGRAF     4  /* graph resolution */
  26. # define T80X25      3  /* text resolution */
  27. # define WHCYMAG     1  /* color quad for normal screen */
  28. # define AL        320  /* array length (screen width) */
  29. # define DS        11  /* number of distinct sums */
  30. # define DT         12  /* DS + 1 */
  31. # define NX         20    /* number of sample rules */
  32.  
  33. char xrule[] =
  34.  
  35.     "00012012000"
  36.     "00021021000"
  37.     "00100221120"
  38.     "00100222120"
  39.     "00102110120"
  40.  
  41.     "01002110110"
  42.     "01002122012"
  43.     "01010122220"
  44.     "01022100222"
  45.     "02001101100"
  46.  
  47.     "02010202120"
  48.     "02011120110"
  49.     "02121112202"
  50.     "10022201212"
  51.     "11021000021"
  52.  
  53.     "20010020211"
  54.     "20101102010"
  55.     "20200011222"
  56.     "20210120222"
  57.     "21000221212"
  58.  
  59.     ;
  60.  
  61. char  xx[4], rule[DT];
  62. int   arule[DS], arr1[AL], arr2[AL];
  63.  
  64. main()
  65. {
  66. int c, i, jj, n;
  67. int  more = 'r';
  68.  
  69.     videopalette(WHCYMAG);                /* white/cyan/magenta */
  70.  
  71.     tuto();
  72.     while (!kbdst()) jj=rand();                /* wait for keypress */
  73.     c=kbdin();                        /* ignore it */
  74.     jj=rand()%NX;
  75.     for (i=0; i<DS; i++) rule[i] = xrule[DS*jj+i];    /* random sample rule */
  76.     rule[DS]=0;
  77.     for (i=0; i<AL; i++) {                /* random initial array */
  78.     if (i%4 == 0) c=rand();
  79.     arr1[i]=c%3; c/=3;};
  80.     videomode(T80X25);
  81.     videoscroll(3,0,4,71,0,3);                /* menu on blue background */
  82.     videoscroll(16,0,21,71,0,3);
  83.     xmenu(jj+1);                    /* show initial rule */
  84.  
  85.     while (more!='n') {                    /* execute multiple runs */
  86.     rmenu();
  87.     lmenu();
  88.     while (0<1) {                    /* set up one run */
  89.     c=kbdin();
  90.     if (c=='g') break;                    /* go draw graph */
  91.     if (c=='q') more='n';                /* quit for good */
  92.     if (more=='n') break;
  93.     switch (c) {
  94.         case 'r':                    /* edit rule */    
  95.         xblnk();
  96.         edrule();
  97.         videocursor(0,3,0);
  98.         rmenu();
  99.         break;
  100.         case 'l':                    /* edit cell string */
  101.         xblnk();
  102.         edline();
  103.         videocursor(0,3,0);
  104.         lmenu();
  105.         break;
  106.         case '#':                    /* read stored rule */
  107.         xmenu(NX);
  108.         n=DS*((i=lim(1,numin(0),NX))-1);
  109.         xmenu(i);
  110.         for (i=0; i<DS; i++) rule[i] = xrule[n+i];
  111.         rmenu();
  112.             break;
  113.         case 'u':
  114.         xblnk();
  115.         for (i=0; i<AL; i++) arr1[i]=0;
  116.         arr1[AL/4]=1;
  117.             arr1[AL/2]=2;
  118.             arr1[(3*AL)/4]=1;
  119.         lmenu();
  120.             break;
  121.     case 'x':                    /* random rule */
  122.         xblnk();
  123.             for (i=0; i<DS; i++) {
  124.             if (i%4 == 0) c = rand();
  125.             rule[i] = '0'+(c%3);
  126.             c/=3;
  127.             };
  128.         rmenu();
  129.         break;
  130.     case 'y':                    /* random line */
  131.         xblnk();
  132.         for (i=0; i<AL; i++) {
  133.             if (i%4 == 0) c = rand();
  134.             arr1[i]=c%3;
  135.             c/=3;
  136.             };
  137.             lmenu();
  138.         break;
  139.         default: break;
  140.         };
  141.     };
  142.     if (more=='n') break;
  143.     do {
  144.     evolve(rule);
  145.     videocursor(0,0,0);
  146.     scrstr("More?");
  147.     videocursor(0,0,30);
  148.     scrstr("y/n/cr");
  149.     more=kbdin();
  150.     } while (more=='\015');
  151.     videomode(T80X25);                    /* reset the screen */
  152.     if (more=='n') break;
  153.     };
  154. }    
  155.  
  156. edrule()                        /* edit the rule */
  157. {
  158. char c;
  159. int  i;
  160.  
  161.     videocursor(0,1,6);                    /* get the rule */
  162.     i=0;
  163.     while (i<DS) {
  164.         videoputc(rule[i],2);
  165.         videoputc('\010',1);
  166.         c = kbdin();
  167.         if (c == '\015') break;
  168.         switch (c) {
  169.         case '0':  case '1': case '2':            /* state */
  170.             rule[i++] = c;
  171.             videoputc(c,1);
  172.             break;
  173.         case ' ':                    /* space = advance */
  174.             videoputc(rule[i++],1);
  175.             break;
  176.         case '\010':                    /* backspace */
  177.             if (i==0) break;
  178.             videoputc(rule[i--],1);
  179.             videoputc(c,1);
  180.             videoputc(c,1);
  181.             break;
  182.     default: break;
  183.         };
  184.     };
  185. }
  186.  
  187. edline() {                        /* edit the line */
  188.  
  189. char c;
  190. int  i, j, k, ii, jj;
  191.  
  192.     videocursor(0,16,0);
  193.     scrstr("insert states using 0, 1, 2");
  194.     videocursor(0,17,0);
  195.     scrstr("move cursor with n(north), s(south), e(east), w(west), or");
  196.     videocursor(0,18,0);
  197.     scrstr("with keyboard arrows. Space, backspace move right and left.");
  198.     videocursor(0,19,0);
  199.     scrstr("( seeks left margin, < absolutely, { up one line, [ down one line");
  200.     videocursor(0,20,0);
  201.     scrstr(") seeks right margin, > absolutely, } up one line, ] down one line");
  202.     videocursor(0,21,0);
  203.     scrstr("carriage return exits");
  204.     jj=4;
  205.     ii=1;
  206.     while (0<1) {
  207.     ii=lim(1,ii,40);
  208.     jj=lim(1,jj,8);
  209.     j=jj-1;
  210.     i=ii-1;
  211.     videocursor(0,j+6,i);
  212.     c=kbdin();
  213.     if (c == '\015') {videoscroll(16,0,21,70,0,3); break;};
  214.     switch (c) {
  215.     case '0':  case '1': case '2':                /* enter  state */
  216.         arr1[40*j+i] = c-'0';
  217.     ii++;
  218.     break;
  219.     case 's': case '\012': case '\320':          jj++; break;    /* down - next line */
  220.     case 'n': case '\013': case '\310':          jj--; break;    /* up   - last line */
  221.     case 'e': case '\014': case '\315': case ' ': ii++; break;    /* space = advance  */
  222.     case 'w': case '\010': case '\313':          ii--; break;    /* backspace */
  223.     case '<': ii=1;  jj=1;  break;  /* absolute left */
  224.     case '{': ii=1;  jj--;  break;  /* left one row up */
  225.     case '(': ii=1;         break;  /* left this row */
  226.     case '[': ii=1;  jj++;  break;  /* left next row */
  227.     case '>': ii=40; jj=40; break;  /* absolute right */
  228.     case '}': ii=40; jj--;  break;  /* right one row up */
  229.     case ')': ii=40;        break;  /* right this row */
  230.     case ']': ii=40; jj++;  break;  /* right next row */
  231.     default: break;
  232.         };
  233.     videocursor(0,j+6,0);
  234.     for (k=0; k<40; k++) videoputc('0'+arr1[40*j+k],1);
  235.     };
  236. }
  237.  
  238. evolve(rule)                        /* display a screen of evolution */
  239. char *rule;
  240. {
  241. int i, j, sum, sum0, sum1, sum2, sum3;
  242.  
  243.     videomode(COLGRAF);                    /* erase the screen */
  244.     videocursor(0,0,0);                    /* top text line */
  245.     scrstr("Rule: ");
  246.     scrstr(rule);
  247.     for (i=0; i<DS; i++) {arule[i] = rule[i]-'0';}
  248.     for (j=8; j<200; j++) videodot(j,AL-1,2);
  249.     for (j=8; j<200; j++) {                /* evolve for 192 generations */
  250.         sum0 = arr1[AL-2] + arr1[AL-1] + arr1[0] + arr1[1] + arr1[2];
  251.         sum1 = arr1[AL-1] + arr1[0] + arr1[1] + arr1[2] + arr1[3];
  252.         arr2[0] = arule[sum0];
  253.         arr2[1] = arule[sum1];
  254.         for (i=2; i<AL-2; i++) {
  255.             sum = arr1[i-2] + arr1[i-1] + arr1[i] + arr1[i+1] + arr1[i+2];
  256.             arr2[i] = arule[sum];
  257.             };
  258.         sum2 = arr1[AL-3] + arr1[AL-2] + arr1[AL-1] + arr1[0] + arr1[1];
  259.         sum3 = arr1[AL-4] + arr1[AL-3] + arr1[AL-2] + arr1[AL-1] + arr1[0];
  260.         arr2[AL-1] = arule[sum2];
  261.         arr2[AL-2] = arule[sum3];
  262.         for (i=0;  i<AL; i++) {videodot(j,i,arr1[i]); arr1[i] = arr2[i];};
  263.     if (kbdst()) {kbdin(); break;};
  264.         }
  265. }
  266.  
  267. tuto()                            /* tutorial and Help screen */
  268. {
  269.     videomode(T80X25);
  270.     videocursor(0,2,0);
  271.     scrstr("<Copyright (C) 1987 - H.V. McIntosh, G. Cisneros S.>");
  272.     videocursor(0,4,0);
  273.     scrstr("        ***** LIFE in One Dimension *****");
  274.     videocursor(0,6,0);
  275.     scrstr("hree States - Black(0), Cyan(1), Magenta(2).");
  276.     videocursor(0,8,0);
  277.     scrstr("Second neighbors - two on each side, five altogether.");
  278.     videocursor(0,10,0);
  279.     scrstr("Totalistic transition rule - random, edited, or stored.");
  280.     videocursor(0,12,0);
  281.     scrstr("Initial Cellular Array - random, edited, or patterned.");
  282.     videocursor(0,14,0);
  283.     scrstr("Some rules are fragile and require several tries before");
  284.     vide